using System;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace EntityKit.Runtime
{
    /// <summary>
    /// AES加密提供者（使用随机IV）
    /// </summary>
    public class AESEncryptionProvider : IEncryptionProvider
    {
        private readonly byte[] _key;
        
        /// <summary>
        /// 使用指定密钥创建AES加密提供者
        /// </summary>
        /// <param name="key">用于加密/解密的密钥</param>
        public AESEncryptionProvider(string key = "EntityKitDefaultKey12345678901234567890")
        {
            if (string.IsNullOrEmpty(key))
                throw new ArgumentException("Key cannot be null or empty", nameof(key));
                
            // 将密钥转换为32字节（256位）
            _key = Encoding.UTF8.GetBytes(key.PadRight(32).Substring(0, 32));
        }
        
        /// <summary>
        /// 加密数据
        /// </summary>
        /// <param name="data">原始数据</param>
        /// <returns>加密后的数据</returns>
        public string Encrypt(string data)
        {
            try
            {
                using var aes = Aes.Create();
                aes.Key = _key;
                aes.GenerateIV(); // 生成随机IV
                
                var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
                byte[] dataBytes = Encoding.UTF8.GetBytes(data);
                byte[] encryptedBytes = encryptor.TransformFinalBlock(dataBytes, 0, dataBytes.Length);
                
                // 将IV和加密数据合并，IV放在前面
                byte[] result = new byte[aes.IV.Length + encryptedBytes.Length];
                Buffer.BlockCopy(aes.IV, 0, result, 0, aes.IV.Length);
                Buffer.BlockCopy(encryptedBytes, 0, result, aes.IV.Length, encryptedBytes.Length);
                
                return Convert.ToBase64String(result);
            }
            catch (Exception ex)
            {
                throw new StorageException("数据加密失败", ex);
            }
        }

        /// <summary>
        /// 异步加密数据
        /// </summary>
        /// <param name="data">原始数据</param>
        /// <returns>加密后的数据</returns>
        public async Task<string> EncryptAsync(string data)
        {
            // 使用Task.Run将计算密集型操作放到线程池线程上执行，避免阻塞主线程
            return await Task.Run(() => Encrypt(data));
        }

        /// <summary>
        /// 解密数据
        /// </summary>
        /// <param name="data">加密数据</param>
        /// <returns>解密后的数据</returns>
        public string Decrypt(string data)
        {
            try
            {
                byte[] fullData = Convert.FromBase64String(data);
                
                using var aes = Aes.Create();
                aes.Key = _key;
                
                // 提取IV（前16字节）
                byte[] iv = new byte[16];
                Buffer.BlockCopy(fullData, 0, iv, 0, iv.Length);
                aes.IV = iv;
                
                // 提取加密数据（剩余部分）
                byte[] encryptedData = new byte[fullData.Length - iv.Length];
                Buffer.BlockCopy(fullData, iv.Length, encryptedData, 0, encryptedData.Length);
                
                var decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
                byte[] decryptedBytes = decryptor.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
                
                return Encoding.UTF8.GetString(decryptedBytes);
            }
            catch (Exception ex)
            {
                throw new StorageException("数据解密失败", ex);
            }
        }

        /// <summary>
        /// 异步解密数据
        /// </summary>
        /// <param name="data">加密数据</param>
        /// <returns>解密后的数据</returns>
        public async Task<string> DecryptAsync(string data)
        {
            // 使用Task.Run将计算密集型操作放到线程池线程上执行，避免阻塞主线程
            return await Task.Run(() => Decrypt(data));
        }
    }
}